#include "Board.h"

Board::Board() {}

Board::~Board(void) {
	std::vector< std::vector<Field*> >::iterator outer;
	std::vector<Field*>::iterator inner;
	for( outer = m_fields.begin() ; outer != m_fields.end() ; outer++ ) {
		for( inner = (*outer).begin() ; inner != (*outer).end() ; inner++ ) {
			delete (*inner);
		}
	}
}

void Board::setBoard(int columns, int rows) {
	m_columns = columns;
	m_rows = rows;
	m_fields.resize(rows);
	std::vector< std::vector<Field*> >::iterator outer;
	std::vector<Field*>::iterator inner;
	for(outer = m_fields.begin() ; outer != m_fields.end() ; outer++ ) {
		(*outer).resize(columns);
		for(inner = (*outer).begin() ; inner != (*outer).end() ; inner++ ) {
			(*inner) = new Field(None);
		}
	}
}

bool Board::placePiece(int column, int row, int player){
	// TODO: Set error handling or not.
	(m_fields.at(row-1).at(column-1))->setOccupancy(player);
	return true;
}

int Board::getOccupancy(int column, int row) {
	if(column < 1 || column > m_columns) return OffBoard;
	if(row < 1 || row > m_rows) return OffBoard;
	return (m_fields.at(row-1).at(column-1))->getOccupancy();
}

std::ostream& operator<<(std::ostream& os, Board& board) {
	std::vector< std::vector<Field*> >::reverse_iterator outer;
	std::vector<Field*>::iterator inner;
	for(outer = board.m_fields.rbegin() ; outer != board.m_fields.rend() ; outer++ ) {
		for(inner = (*outer).begin() ; inner != (*outer).end() ; inner++ ) {
			// TODO make signs interchangeable not hardcoded
			switch ( (*inner)->getOccupancy() ) {
				case None : {
					os << '.';
					break;
				}
				case Player1 : {
					os << 'P';
					break;
				}
				case Player2 : {
					os << 'p';
					break;
				}
				case Unavailable : {
					os << '*';
					break;
				}
			}
		}
		os << std::endl;
	}
	return os;
}

void Board::movePiece(const Move &gameMove) {
	*(m_fields[gameMove.t_row-1][gameMove.t_col-1]) = *(m_fields[gameMove.f_row-1][gameMove.f_col-1]);
	m_fields[gameMove.f_row-1][gameMove.f_col-1]->setOccupancy(None);
}

int Board::getColumnSize() {
	return m_columns;
}

int Board::getRowSize() {
	return m_rows;
}

void Board::countPieces( int &pl1, int &pl2 ) {
	pl1 = pl2 = 0;
	std::vector< std::vector<Field*> >::iterator outer;
	std::vector<Field*>::iterator inner;
	for( outer = m_fields.begin() ; outer != m_fields.end() ; outer++ ) {
		for( inner = (*outer).begin() ; inner != (*outer).end() ; inner++ ) {
			if((*inner)->getOccupancy() == Player1) pl1++;
			else if((*inner)->getOccupancy() == Player2) pl2++;
		}
	}
}



void Board::getPlayerPieces(int player, std::vector<std::pair<int,int> >& pieces) {
	for(unsigned int i = 0 ; i < m_fields.size() ; ++i ) {
		for(unsigned int j = 0 ; j < m_fields.at(i).size() ; ++j) {
			if(m_fields.at(i).at(j)->getOccupancy() == player) {
				pieces.push_back(std::pair<int,int>(j+1,i+1));
			}
		}
	}
}

//------ Code for Move class 
// TODO Move to different file.

std::string Move::display() const {
	std::stringstream output;
	output << "from ("<< f_col << ',' << f_row << ")\n";
	output << "to   ("<< t_col << ',' << t_row << ')';
	return output.str();
}

std::ostream& operator<<(std::ostream& os, Move gameMove) {
	os << gameMove.f_col << " " << gameMove.f_row << " ";
	os << gameMove.t_col << " " << gameMove.t_row;
	return os;
}